import { Subject } from 'rxjs';

interface SSEConnection {
  subject: Subject<any>;
  heartbeatTimer?: NodeJS.Timeout;
  createdAt: Date;
  lastActivity: Date;
}

export class SubjectManager {
  private static connections: Map<string, SSEConnection> = new Map<
    string,
    SSEConnection
  >();
  private static cleanupTimer?: NodeJS.Timeout;
  private static readonly MAX_IDLE_TIME = 5 * 60 * 1000; // 5分钟无活动自动清理
  private static readonly CLEANUP_INTERVAL = 60 * 1000; // 每分钟检查一次

  // 兼容性：保持原有的SseSubject接口
  public static get SseSubject() {
    return {
      get: (clientId: string) => {
        const connection = SubjectManager.connections.get(clientId);
        return connection?.subject;
      },
      set: (clientId: string, subject: Subject<any>) => {
        SubjectManager.addConnection(clientId, subject);
      },
      delete: (clientId: string) => {
        SubjectManager.removeConnection(clientId);
      },
      entries: () => {
        const entries: [string, Subject<any>][] = [];
        for (const [id, connection] of SubjectManager.connections.entries()) {
          entries.push([id, connection.subject]);
        }
        return entries;
      },
    };
  }

  private static addConnection(clientId: string, subject: Subject<any>) {
    // 清理旧连接
    SubjectManager.removeConnection(clientId);

    const connection: SSEConnection = {
      subject,
      createdAt: new Date(),
      lastActivity: new Date(),
    };

    SubjectManager.connections.set(clientId, connection);
    SubjectManager.startCleanupTimer();
  }

  private static removeConnection(clientId: string) {
    const connection = SubjectManager.connections.get(clientId);
    if (connection) {
      // 清理心跳定时器
      if (connection.heartbeatTimer) {
        clearInterval(connection.heartbeatTimer);
      }

      // 关闭Subject
      if (!connection.subject.closed) {
        connection.subject.complete();
      }

      SubjectManager.connections.delete(clientId);
    }
  }

  public static updateActivity(clientId: string) {
    const connection = SubjectManager.connections.get(clientId);
    if (connection) {
      connection.lastActivity = new Date();
    }
  }

  public static setHeartbeatTimer(clientId: string, timer: NodeJS.Timeout) {
    const connection = SubjectManager.connections.get(clientId);
    if (connection) {
      // 清理旧的定时器
      if (connection.heartbeatTimer) {
        clearInterval(connection.heartbeatTimer);
      }
      connection.heartbeatTimer = timer;
    }
  }

  private static startCleanupTimer() {
    if (!SubjectManager.cleanupTimer) {
      SubjectManager.cleanupTimer = setInterval(() => {
        SubjectManager.cleanupIdleConnections();
      }, SubjectManager.CLEANUP_INTERVAL);
    }
  }

  private static cleanupIdleConnections() {
    const now = new Date();
    const toRemove: string[] = [];

    for (const [clientId, connection] of SubjectManager.connections.entries()) {
      const idleTime = now.getTime() - connection.lastActivity.getTime();
      if (
        idleTime > SubjectManager.MAX_IDLE_TIME ||
        connection.subject.closed
      ) {
        toRemove.push(clientId);
      }
    }

    toRemove.forEach((clientId) => {
      SubjectManager.removeConnection(clientId);
    });

    // 如果没有连接了，停止清理定时器
    if (SubjectManager.connections.size === 0 && SubjectManager.cleanupTimer) {
      clearInterval(SubjectManager.cleanupTimer);
      SubjectManager.cleanupTimer = undefined;
    }
  }

  public static getConnectionCount(): number {
    return SubjectManager.connections.size;
  }

  public static cleanup() {
    // 清理所有连接
    for (const clientId of SubjectManager.connections.keys()) {
      SubjectManager.removeConnection(clientId);
    }

    // 清理定时器
    if (SubjectManager.cleanupTimer) {
      clearInterval(SubjectManager.cleanupTimer);
      SubjectManager.cleanupTimer = undefined;
    }
  }
}
